init();

var className = null;
var functionName = null;

function start_activity()
{
    // com.cmic.sso.secapp.MainActivity
    // com.cmic.sso.secapp.AppListActivity
    // com.cmic.sso.secapp.WebActivity
    // com.cmic.sso.secapp.FileViewActivity
    // com.cmic.sso.secapp.WebHomeActivity
   Java.perform(function ()
   {
       var main = getInstance("com.cmic.sso.secapp.MainActivity");
       var current_application = Java.use('android.app.ActivityThread').currentApplication();
       var context = current_application.getApplicationContext();
       var class_class = Java.use('com.cmic.sso.secapp.FileViewActivity').class;
       var intent = Java.use('android.content.Intent').$new(context, class_class)
       main.startActivity(intent)
   });
};


rpc.exports =
{
    getfunction: function (class_name)
    {
        className = class_name
        getClassMethodOne(class_name);
    },

    overloadhook: function (methods)
    {
        hookMethods(methods);
    },

    callmethod: function (methods)
    {
        callMethods(methods)
    },
};

function getClass(className)
{
    return Java.use(className).class;
}

function getInstance(className)
{
    var retInstance = null;
    Java.perform(function ()
    {
        Java.choose(className,
        {
            onMatch: function (instance)
            {
                retInstance = instance;
            },
            onComplete: function ()
            {

            }
        });
    });
    return retInstance;
}

function init()
{
    // className = "com.hx.hxsocket.MainActivity"
    // functionName = "test"
    // hookTwo()
    // getClassMethodOne();
    // proxyHook();
    // vpnHook();
    // Java.perform(function()
    // {
    //     var MainActivity = Java.use("com.hx.hxsocket.MainActivity")
    //     MainActivity.test.overload().implementation = function ()
    //     {
    //         var ret = this.test();
    //         console.log(ret)
    //         return ret;
    //     }
    // });
};

function hookMethods(methods_list)
{
    Java.perform(function()
    {
        try
        {
            console.log(methods_list);
            var cls = Java.use(className);
            var methods = cls.class.getDeclaredMethods();
            for (var i = 0; i < methods.length; i++)
            {
                var methodName = methods[i].getName();
                var overloadNum = cls[methodName].overloads.length;
                for (var n = 0; n < methods_list.length; n++)
                {
                    var method = methods[i].toString()

                    if (method != methods_list[n])
                    {
                        continue;
                    }
                    else
                    {
                        for (var index = 0; index < overloadNum; index++)
                        {
                            console.log(index);
                            cls[methodName].overloads[index].implementation = function ()
                            {
                                var ret = this[methodName].apply(this, arguments);
                                console.log(methodName);
                                send(format_hook_info(methodName, arguments, ret));
                                return ret;
                            }
                        }
                    }
                }
            }
        }
        catch (e)
        {
            console.log(e);
        }
    });
}

function hookAllTwo()
{
     Java.perform(function()
    {
        var cls = Java.use("com.hx.hxsocket.MainActivity");
        var methods = cls.class.getDeclaredMethods();

        for (var i = 0; i < methods.length; i++)
        {
            var methodName = methods[i].getName();
            var overloadNum = cls[methodName].overloads.length;

            if (methodName != functionName)
                continue;

            send(methodName);
            for (var index = 0; index < overloadNum; index++)
            {
                cls[methodName].overloads[index].implementation = function ()
                {
                    var argumentsNum = arguments.length;
                    for (var i = 0; i < argumentsNum; argumentsNum++)
                    {
                        console.log(arguments[i]);
                    }
                    var ret = this[methodName].apply(this, arguments);
                    console.log(ret);
                    return ret;
                }
                break;
            }
        }
    });
}

function hookAllOne()
{
    Java.perform(function()
    {
        var cls = Java.use("com.hx.hxsocket.MainActivity");
        var methods = cls.class.getDeclaredMethods();
        methods.forEach(function (method)
        {
            var methodName = method.getName();
            var overloads = cls[methodName].overloads;
            if (methodName != "test")
                return;

            overloads.forEach(function (overload)
            {
                overload.implementation = function ()
                {
                    for (var j = 0; j < arguments.length; j++)
                    {
                        console.log(arguments[j])
                    }
                    var ret = this[methodName].apply(this, arguments);
                    console.log(ret)
                    return ret;
                }
            });
        });
    });


}

function getClassMethodOne(class_name)
{
    Java.perform(function()
    {
        try
        {
            var currentClass = Java.use(class_name);
            var methods = currentClass.class.getDeclaredMethods();
            var array = new_json_array()
            for(var i  =0; i < methods.length; i++)
            {
                var currentMethod = methods[i];
                array.put(currentMethod)
            }
            send(format("functions",array.toString()));
        }
        catch (e)
        {
             console.log("getClassMethodOne exception.")
             send(format("functions", "null"));
             console.log()
        }

    });
}

function getClassMethodTwo()
{
    Java.perform(function()
    {
        function enumMethods(targetClass)
        {
            var hook = Java.use(targetClass);
            var ownMethods = hook.class.getDeclaredMethods();
            return ownMethods;
        }
        var method = enumMethods(className)
        method.forEach(function(msg)
        {
            send(msg.toString());
        });
    });
}

function new_json_object(args)
{
    var json = Java.use('org.json.JSONObject').$new();
    return json;
}

function new_json_array(args)
{
    var json_ary = Java.use('org.json.JSONArray').$new();
    return json_ary;
}

function format_hook_info(method, arguments_ex, ret)
{
    var json = new_json_object()
    json.put("name","hook");
    if (null != method)
        json.put("method",method);
    if (null != ret)
        console.log(ret);
        json.put("return",ret);

    var array = new_json_array();
    var argumentsNum = arguments_ex.length;
    for (var i = 0; i < argumentsNum; argumentsNum++)
    {
        array.put(arguments_ex[i])
    }

    json.put("arguments",array.toString());

    return json.toString();
}

function format(name,data)
{
    var json = new_json_object();
    json.put("name",name);
    json.put("data",data);
    return json.toString();
}


//========================================================第二版=========================================================
init();

var className = null;
var functionName = null;

function start_activity()
{
    // com.cmic.sso.secapp.MainActivity
    // com.cmic.sso.secapp.AppListActivity
    // com.cmic.sso.secapp.WebActivity
    // com.cmic.sso.secapp.FileViewActivity
    // com.cmic.sso.secapp.WebHomeActivity
   Java.perform(function ()
   {
       var main = getInstance("com.cmic.sso.secapp.MainActivity");
       var current_application = Java.use('android.app.ActivityThread').currentApplication();
       var context = current_application.getApplicationContext();
       var class_class = Java.use('com.cmic.sso.secapp.FileViewActivity').class;
       var intent = Java.use('android.content.Intent').$new(context, class_class)
       main.startActivity(intent)
   });
};


rpc.exports =
{
    getfunction: function (class_name)
    {
        className = class_name
        getClassMethodOne(class_name);
    },

    overloadhook: function (methods)
    {
        hookMethods(methods);
    },

    callmethod: function (methods)
    {
        callMethods(methods)
    },
};

function getClass(className)
{
    return Java.use(className).class;
}

function getInstance(className)
{
    var retInstance = null;
    Java.perform(function ()
    {
        Java.choose(className,
        {
            onMatch: function (instance)
            {
                retInstance = instance;
            },
            onComplete: function ()
            {

            }
        });
    });
    return retInstance;
}

function init()
{
    // className = "com.hx.hxsocket.MainActivity"
    // functionName = "test"
    // hookTwo()
    // getClassMethodOne();
    // proxyHook();
    // vpnHook();
    // Java.perform(function()
    // {
    //     var MainActivity = Java.use("com.hx.hxsocket.MainActivity")
    //     MainActivity.test.overload().implementation = function ()
    //     {
    //         var ret = this.test();
    //         console.log(ret)
    //         return ret;
    //     }
    // });
};

function hookOverloadsMethod(className,methodName)
{
    Java.perform(function()
    {
        try
        {
            var cls = Java.use(className);
            var overloadNum = cls[methodName].overloads.length;
            for (var index = 0; index < overloadNum; index++)
            {
                cls[methodName].overloads[index].implementation = function ()
                {
                    var args = []
                    for (var j = 0; j < arguments.length; j++)
                    {
                        args[j] = arguments[j] + ""
                    }
                    var json = new_json_object();
                    json.put("method", methodName);
                    json.put("arguments", JSON.stringify(args));
                    var ret = this[methodName].apply(this, arguments);
                    if (ret != undefined)
                    {
                        json.put("return",  JSON.stringify(ret));
                    }
                    else
                    {
                        json.put("return", "无返回值");
                    }
                    send(json.toString());
                    return ret;
                }
            }
        }
        catch (e)
        {
            console.log(e);
        }
    });
}

function getOverloadNum(className,methodName)
{
    var cls = Java.use(className);
    var overloadNum = cls[methodName].overloads.length;
    return overloadNum;
}

function hookGeneralMethods(className,methodName,index)
{
    Java.perform(function()
    {
        try
        {
            var cls = Java.use(className);
            cls[methodName].overloads[index].implementation = function ()
            {
                var args = []
                for (var j = 0; j < arguments.length; j++)
                {
                    args[j] = arguments[j] + ""
                }
                var json = new_json_object();
                json.put("method", methodName);
                json.put("arguments", JSON.stringify(args));
                var ret = this[methodName].apply(this, arguments);
                if (ret != undefined)
                {
                    json.put("return",  JSON.stringify(ret));
                }
                else
                {
                    json.put("return", "无返回值");
                }
                send(json.toString());
                return ret;
            }
        }
        catch (e)
        {
            console.log(e);
        }
    });
}

function hookMethods(methods_list)
{
    Java.perform(function()
    {
        try
        {
            var cls = Java.use('com.hx.hxsocket.MainActivity');
            var methods = cls.class.getDeclaredMethods();
            for (var i = 0; i < methods.length; i++)
            {
                var methodName = methods[i].getName();
                var overloadNum = cls[methodName].overloads.length;
                for (var n = 0; n < methods_list.length; n++)
                {
                    if (methodName != methods_list[n])
                    {
                        continue;
                    }
                    else
                    {
                        for (var index = 0; index < overloadNum; index++)
                        {
                            cls[methodName].overloads[index].implementation = function ()
                            {
                                var args = []
                                for (var j = 0; j < arguments.length; j++)
                                {
                                    args[j] = arguments[j] + ""
                                }
                                var json = new_json_object();
                                json.put("method", methodName);
                                json.put("arguments", JSON.stringify(args));
                                var ret = this[methodName].apply(this, arguments);
                                if (ret != undefined)
                                {
                                    json.put("return",  JSON.stringify(ret));
                                }
                                else
                                {
                                    json.put("return", "无返回值");
                                }
                                send(json.toString());
                                return ret;
                            }
                        }
                    }
                }
            }
        }
        catch (e)
        {
            console.log(e);
        }
    });
}


function hookAllTwo()
{
     Java.perform(function()
    {
        var cls = Java.use("com.hx.hxsocket.MainActivity");
        var methods = cls.class.getDeclaredMethods();

        for (var i = 0; i < methods.length; i++)
        {
            var methodName = methods[i].getName();
            var overloadNum = cls[methodName].overloads.length;

            if (methodName != functionName)
                continue;

            send(methodName);
            for (var index = 0; index < overloadNum; index++)
            {
                cls[methodName].overloads[index].implementation = function ()
                {
                    var argumentsNum = arguments.length;
                    for (var i = 0; i < argumentsNum; argumentsNum++)
                    {
                        console.log(arguments[i]);
                    }
                    var ret = this[methodName].apply(this, arguments);
                    console.log(ret);
                    return ret;
                }
                break;
            }
        }
    });
}

function hookAllOne()
{
    Java.perform(function()
    {
        var cls = Java.use("com.hx.hxsocket.MainActivity");
        var methods = cls.class.getDeclaredMethods();
        methods.forEach(function (method)
        {
            var methodName = method.getName();
            var overloads = cls[methodName].overloads;
            if (methodName != "test")
                return;

            overloads.forEach(function (overload)
            {
                overload.implementation = function ()
                {
                    for (var j = 0; j < arguments.length; j++)
                    {
                        console.log(arguments[j])
                    }
                    var ret = this[methodName].apply(this, arguments);
                    console.log(ret)
                    return ret;
                }
            });
        });
    });


}

function getClassMethodOne(className)
{
    Java.perform(function()
    {
        try
        {
            var currentClass = Java.use(className);
            var methods = currentClass.class.getDeclaredMethods();
            var array = new_json_array()
            for(var i  =0; i < methods.length; i++)
            {
                var currentMethod = methods[i];
                array.put(currentMethod)
            }
            send(format("functions",array.toString()));
        }
        catch (e)
        {
             console.log("getClassMethodOne exception.")
             send(format("functions", "null"));
             console.log()
        }

    });
}

function getClassMethodTwo()
{
    Java.perform(function()
    {
        function enumMethods(targetClass)
        {
            var hook = Java.use(targetClass);
            var ownMethods = hook.class.getDeclaredMethods();
            return ownMethods;
        }
        var method = enumMethods(className)
        method.forEach(function(msg)
        {
            send(msg.toString());
        });
    });
}

function new_json_object(args)
{
    var json = Java.use('org.json.JSONObject').$new();
    return json;
}

function new_json_array(args)
{
    var json_ary = Java.use('org.json.JSONArray').$new();
    return json_ary;
}

function format(name,data)
{
    var json = new_json_object();
    json.put("name",name);
    json.put("data",data);
    return json.toString();
}


